import React, { useEffect, useState, Key } from 'react'
import {
  Button,
  Checkbox,
  Form,
  Input,
  Card,
  Space,
  Table,
  Tag,
  Tooltip,
  message,
} from 'antd'

import type { ColumnsType } from 'antd/es/table'
import { SearchOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'

import { useNavigate } from 'react-router-dom'
// 引入发送请求的函数
import {
  reqDelHospitalSet,
  reqGetHospitalSets,
  reqBatchDelHospitalSet,
} from '@api/hospital/hospitalSet'
// 引入ts类型
import {
  IhospitalSets,
  IhospitalSetItem,
} from '@api/hospital/hospitalSet/model/hospitalSetTypes'

// flag为true,则查询数据时有筛选条件,为false,则没有筛选条件
let flag = false

export default function HospitalSet() {
  const navigate = useNavigate()
  //创建form实例
  const [form] = Form.useForm()
  // 调用useState<泛型> 是在定义当前状态的数据类型.如果不写,数据类型就是never[].后期赋值时,ts检查会失败
  const [hospitalSets, setHospitalSets] = useState<IhospitalSets>([])
  // 分页相关的状态
  const [total, setTotal] = useState(0)
  const [pageSize, setPageSize] = useState(5)
  const [page, setPage] = useState(1)

  // 处理批量删除按钮是否禁用的状态
  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([])

  // 加载效果
  const [loading, setLoading] = useState(false)
  // useEffect的外层函数,不能写async
  useEffect(() => {
    // 组件挂载获取医院设置数据
    getHospitalSets(page, pageSize)
  }, [])

  async function getHospitalSets(page: number, pageSize: number) {
    setLoading(true)
    let result
    // 发送请求之前,要判断flag,为true则参数有hosname和hoscode.为false则不添加hosname和hoscode
    if (flag) {
      // 拿到hosname和hoscode
      // antd中给我们提供了对应的api.可以在任何地方获取到表单中数据
      // 1.利用Form.useForm创建form实例
      // 2. 用form实例和对应的Form组件进行绑定
      // 3. form.getFieldsValues() 返回表单中的所有数据
      const { hosname, hoscode } = form.getFieldsValue()
      result = await reqGetHospitalSets(page, pageSize, hosname, hoscode)
    } else {
      result = await reqGetHospitalSets(page, pageSize)
    }

    // console.log(result)
    // 将数据存储到状态中
    setHospitalSets(result.records)
    setTotal(result.total)
    setLoading(false)
  }

  // 查询按钮的事件处理函数
  const onFinish = () => {
    // 重新发送请求,获取表单数据
    flag = true
    getHospitalSets(1, pageSize)
    setPage(1)
  }

  // 清空按钮的事件处理函数
  const clear = () => {
    // 清空表单
    form.setFieldsValue({ hosname: undefined, hoscode: undefined })

    flag = false
    getHospitalSets(1, pageSize)
    setPage(1)
  }

  // 决定了表格中的列以及表头信息
  // 传入泛型,告诉Table传入的数组中每一个对象的类型
  const columns: ColumnsType<IhospitalSetItem> = [
    {
      title: '序号', //表头信息
      //1. 不写render的时候dataIndex的值是dataSource中对象的属性.并在这一列渲染每一条数据这个属性的值
      //2. 写了render,则渲染render的返回值.但是dataIndex此时还有用.决定了render函数第一个参数是什么
      // dataIndex: 'name',
      // key: 'name', //虽然是列表渲染的key,但是我们用不到.
      render: (text, record, index) => {
        // text的值受到dataIndex的影响: 1.如果写dataIndex.则text就是每一条数据中dataIndex所对应的属性的值 2.如果不写dataIndex.则text就是每一条数据
        // console.log(text)

        return index + 1
      }, // render的值是一个回调函数,函数的返回值是什么,则这一列就渲染什么
      // fixed: true,
      align: 'center', //这一列内容水平居中
      width: 80, //设置这一列的宽度
    },
    {
      title: '医院名称',
      dataIndex: 'hosname',
    },
    {
      title: '医院编号',
      dataIndex: 'hoscode',
    },
    {
      title: 'api基础路径',

      dataIndex: 'apiUrl',
    },
    {
      title: '签名',
      dataIndex: 'signKey',
    },
    {
      title: '联系人姓名',
      dataIndex: 'contactsName',
    },
    {
      title: '联系人手机号',
      dataIndex: 'contactsPhone',
    },
    {
      title: '操作',
      key: 'action',
      render: (_, record) => {
        return (
          <Space>
            <Tooltip title="修改医院">
              <Button
                type="primary"
                icon={<EditOutlined />}
                onClick={() => {
                  navigate('/syt/hospital/hospitalSet/update', {
                    state: record.id,
                  })
                }}
              ></Button>
            </Tooltip>

            <Tooltip title="删除医院">
              <Button
                type="primary"
                danger
                icon={<DeleteOutlined />}
                onClick={async () => {
                  await reqDelHospitalSet(record.id)
                  message.success('删除成功')
                  getHospitalSets(page, pageSize)
                }}
              ></Button>
            </Tooltip>
          </Space>
        )
      },
      //让操作这一列固定
      fixed: 'right',
      width: 120,
    },
  ]
  return (
    <Card>
      <Form
        // 只要表单中的表单元素值被修改了.则触发onValuesChange
        onValuesChange={(changedValues, allValues) => {
          // console.log(changedValues, allValues)
          // 主要用户在表单中输入,就直接flag设置为false.强制用户又筛选条件的时候必须点击查询按钮
          flag = false
        }}
        form={form}
        //  让表单中的表单元素在一行排列
        layout="inline"
        name="basic" //当前form表单的名字
        // antd中也有栅格系统,一行是24份
        // 表单中描述文本这一列在一行中占8份
        // labelCol={{ span: 8 }}
        // 表单这一列占16份
        // wrapperCol={{ span: 16 }}
        // 初始数据
        // initialValues={{ remember: false, username: '嘿嘿嘿' }}
        // 点击提交按钮,如果表单校验成功,则onFinish触发
        onFinish={onFinish}
        // 点击提交按钮,如果表单校验失败,则onFinishFailed触发
        // onFinishFailed={onFinishFailed}
      >
        <Form.Item
          // 用于给当前表单元素,添加描述文本
          // label="Username"
          name="hosname"
          // 校验规则
          // required: true这个表单项必填
          // message 就是表单校验不通过的提示信息
          // rules={[{ required: true, message: 'Please input your username!' }]}
        >
          <Input placeholder="医院名称" />
        </Form.Item>

        <Form.Item
          // label="Password"
          name="hoscode"
          // rules={[{ required: true, message: 'Please input your password!' }]}
        >
          <Input placeholder="医院编码" />
        </Form.Item>

        {/* <Form.Item
          name="remember"
          valuePropName="checked" //控制值的属性名叫checked
          // offset是表单元素左侧偏移8份的位置
          wrapperCol={{ offset: 8, span: 16 }}
        >
          <Checkbox>Remember me</Checkbox>
        </Form.Item> */}

        <Form.Item>
          {/* Button有htmlType="submit"则表示这个按钮是当前表单的提交按钮 */}
          <Button
            type="primary"
            htmlType="submit"
            style={{ marginRight: 10 }}
            icon={<SearchOutlined />}
          >
            查询
          </Button>
          <Button type="default" onClick={clear}>
            清空
          </Button>
        </Form.Item>
      </Form>
      <div style={{ marginTop: 20, marginBottom: 20 }}>
        <Button
          type="primary"
          style={{ marginRight: 10 }}
          onClick={() => {
            navigate('/syt/hospital/hospitalSet/add')
          }}
        >
          添加
        </Button>
        <Button
          type="primary"
          danger
          disabled={!selectedRowKeys.length}
          onClick={async () => {
            await reqBatchDelHospitalSet(selectedRowKeys)
            message.success('批量删除成功')
            getHospitalSets(page, pageSize)
          }}
        >
          批量删除
        </Button>
      </div>
      {/* colums决定了表格中有多少列, dataSource决定了渲染什么数据
      scroll 让表格滚动 x 表示水平方向滚动 1500表示滚动的宽度 */}
      <Table
        loading={loading}
        columns={columns}
        dataSource={hospitalSets}
        scroll={{ x: 1500 }}
        // 表格渲染边框
        bordered
        rowKey={'id'} // 表示渲染每一行数据时,使用数据中的id作为key值
        // 用来配置table中自带的分页器
        pagination={{
          current: page, //控制分页器高亮页码
          total, // 数据总数
          pageSize, //每页条数
          // 在分页器前面自定义渲染的内容
          showTotal(total, range) {
            return `总共:${total}条`
          },
          // 展示修改每页条数的下拉框
          showSizeChanger: true,
          // 自定义每页条数下拉框的选项
          pageSizeOptions: [2, 5, 10],
          // 展示快速跳转
          showQuickJumper: true,
          // 点击分页器触发的事件
          onChange(page, pageSize) {
            // page  点击了页码
            // pageSize 当前选择的一页多少条
            // console.log(page, pageSize)
            setPageSize(pageSize)
            setPage(page)

            // 发送请求,重新获取数据
            getHospitalSets(page, pageSize)
          },
        }}
        // 让表格展示复选框
        rowSelection={{
          onChange(selectedRowKeys) {
            // console.log(selectedRowKeys)
            setSelectedRowKeys(selectedRowKeys)
          },
        }}
      />
    </Card>
  )
}
